package org.mtmi.midi;


import java.util.ArrayList;
import java.util.List;

import rwmidi.*;

public class MidiManager {
	
	public List<MidiInput> inputs;
	public List<MidiOutput> outputs;
	private static MidiManager instance;
	
	private MidiManager() {
		super();
	}
	
	public static MidiManager getInstance() {
		if (instance == null) {
			instance = new MidiManager();
		}
		return instance;
	}
	
	public void init() {
		
		inputs = new ArrayList<MidiInput>();
		outputs = new ArrayList<MidiOutput>();
		
		
		// Create Midi input for each device.
		for (int i=0;i<RWMidi.getInputDevices().length;i++) {
			
				inputs.add(RWMidi.getInputDevices()[i].createInput());
				System.out.println("Midi Input detected devices: "+inputs.get(i).getName());

			
		}

		// Create Midi otput for each device.
		
		for (int i=0;i<RWMidi.getOutputDevices().length ;i++) {
			
			// Do not use Microsoft GS Wavetable SW Synth as an output device ...
			// User has to configure the midi mapper to avoid conflicts
			// as Microsoft GS Wavetable SW Synth is routed by default in the Midi Mapper.
			if (!RWMidi.getOutputDeviceNames()[i].toString().equals("Microsoft GS Wavetable SW Synth Unknown vendor") ) 
			{
				outputs.add(RWMidi.getOutputDevices()[i].createOutput());
				System.out.println("Midi Ouput detected devices: "+RWMidi.getOutputDevices()[i].createOutput().getName());
			}
			
		}

	}
	
	public MidiInput getMidiInput(int device) {
		return inputs.get(device);
	}
	
	public MidiOutput getMidiOutput(int device) {
		return outputs.get(device);
	}
	
	public void dispose() {
		
		// Close all Midi inputs.
		for (int i=0;i< inputs.size();i++) {
			inputs.get(i).close();
			inputs.get(i).closeMidi();
		}
		
		// Close all midi outputs.
		for (int i=0;i< outputs.size();i++) {
			outputs.get(i).closeMidi();
		}

	}
	
	/** @return the list of available midi outputs */
	public MidiOutput[] getMidiOutputs() {
		return outputs.toArray( new MidiOutput[ outputs.size() ] );
	}
	
	public int getIndexOf( MidiOutput mo ) {
		return outputs.indexOf( mo );
	}
}
